#include <string.h>
#include <stdlib.h>
#include "array_queue.h"

int aqueue_init(aqueue_t **s, int capacity, int size)
{
    if (NULL != *s) // 惩罚使用野指针初始化的人
        return -1;

    *s = malloc(sizeof(aqueue_t));
    if (NULL == *s)
        return -1;
    
    // 多申请一个空间，队列判断满会浪费一个空间
    (*s)->base = calloc(capacity + 1, size); // calloc 会初始化为 0
    if (NULL == (*s)->base) {
        free(*s);
        *s = NULL;
        return -1;
    }

    (*s)->capacity = capacity; // 显示的容量仍是用户指定的，只是在计算的时候用 显示的容量 + 1
    (*s)->head = (*s)->tail = 0;
    (*s)->size = size;

    return 0;
}

int aqueue_empty(aqueue_t *s)
{
    return s->head == s->tail;
}

int aqueue_full(aqueue_t *s)
{
    return (s->tail + 1) % (s->capacity + 1) == s->head;
}

int aqueue_push(aqueue_t *s, const void *data)
{
    if (aqueue_full(s))
        return -1;

    memcpy((char *)(s->base) + s->tail * s->size, data, s->size);

    s->tail++;
    s->tail %= s->capacity + 1;

    return 0;
}

int aqueue_pop(aqueue_t *s, void *elem)
{
    if (aqueue_empty(s))
        return -1;
    
    
    memcpy(elem, (char *)(s->base) + s->head * s->size, s->size);
    memset((char *)(s->base) + s->head * s->size, '\0', s->size);

    s->head++;
    s->head %= s->capacity + 1;

    return 0;
}

void aqueue_destroy(aqueue_t **s)
{
    free((*s)->base);
    (*s)->base = NULL;
    free(*s);
    *s = NULL;
}

